<!--
 * @Author: 张俊辉 zhangjunhui@mangocosmos.com
 * @Date: 2025-04-25 16:00:50
 * @LastEditors: 张俊辉 zhangjunhui@mangocosmos.com
 * @LastEditTime: 2025-05-09 09:40:35
 * @FilePath: \threejs\my-vue-project\src\components\HelloWorld.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  three.js坐标轴颜色红R、绿G、蓝B分别对应坐标系的x、y、z轴，对于three.js的3D坐标系默认y轴朝上
  <div id="canvas">11</div>
</template>

<script>
// 引入three.js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import Stats from './build/stats.module'
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  mounted() {
    // 实例化一个gui对象
    const gui = new GUI()
    //改变交互界面style属性
    gui.domElement.style.right = '0px'
    gui.domElement.style.width = '300px'
    console.log('HelloWorld')
    // 创建场景
    const scene = new THREE.Scene()
    //修改背景颜色，颜色支持十六进制、rgb、hsl、贴图等
    scene.background = new THREE.Color('#0E419C')
    // 创建相机
    const camera = new THREE.PerspectiveCamera(
      75, //视角
      window.innerWidth / window.innerHeight, //宽高比
      0.1, //近平面
      1000 //远平面
    )
    // 设置相机位置
    // camera.position.z = 5
    camera.position.set(100, 100, 100)
    camera.far = 10000

    camera.updateProjectionMatrix()
    camera.lookAt(0, 0, 0) //原点
    // 创建渲染器
    const renderer = new THREE.WebGLRenderer({
      alpha: true
      // canvas: document.getElementById('canvas')
    })
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)
    //几何模型
    // 设置几何体长宽高，也就是x、y、z三个方向的尺寸
    //对比三个参数分别对应xyz轴哪个方向
    const geometry = new THREE.BoxGeometry(10, 10, 10)
    // 创建材质
    const material = new THREE.MeshBasicMaterial({
      color: 0x00ff00, //设置透明度
      transparent: true, //开启透明
      opacity: 0.5
    })
    //MeshLambertMaterial受光照影响
    const material2 = new THREE.MeshLambertMaterial({
      transparent: true, //开启透明
      opacity: 0.5
    })

    const light1 = new THREE.AmbientLight(0xff0000, 0.5) // 红色，强度为0.5
    // 创建网络
    const cube = new THREE.Mesh(geometry, material2) //、网络添加到场景
    scene.add(cube)

    // const light = new THREE.DirectionalLight(0xffffff, 1)
    // // 设置模型mesh的xyz坐标
    // light.position.set(10, 0, 0)
    // scene.add(light)

    // const helper = new THREE.DirectionalLightHelper(light, 1)
    // scene.add(helper)
    //点光源：两个参数分别表示光源颜色和光照强度
    // 参数1：0xffffff是纯白光,表示光源颜色
    // 参数2：1.0,表示光照强度，可以根据需要调整
    const pointLight = new THREE.PointLight(0xffffff, 1.0)
    pointLight.intensity = 10000.0 //光照强度
    //点光源位置
    pointLight.position.set(1000, 1000, 1000) //点光源放在x轴上
    scene.add(pointLight)
    // AxesHelper：辅助观察的坐标系
    const axesHelper = new THREE.AxesHelper(150)
    scene.add(axesHelper)

    //创建stats对象
    const stats = new Stats()
    //stats.domElement:web页面上输出计算结果,一个div元素，
    document.body.appendChild(stats.domElement)
    // 渲染函数
    function animate() {
      stats.update()
      renderer.render(scene, camera)
      // 旋转
      cube.rotation.x += 0.01
      cube.rotation.y += 0.01

      requestAnimationFrame(animate)
    }
    animate()
    gui.add(cube.position, 'x', 0, 1000)
    gui.add(cube.position, 'y', 0, 1100)
    gui.add(cube.position, 'z', 0, 1800)

    // // 创建场景
    // const scene = new THREE.Scene()
    // // 创建相机
    // const camera = new THREE.PerspectiveCamera(
    //   75,
    //   window.innerWidth / window.innerHeight,
    //   0.1,
    //   1000
    // )
    // // 创建渲染器
    // const renderer = new THREE.WebGLRenderer()
    // 设置相机控件轨道控制器OrbitControls
    const controls = new OrbitControls(camera, renderer.domElement)
    // 如果OrbitControls改变了相机参数，重新调用渲染器渲染三维场景
    controls.addEventListener('change', function () {
      renderer.render(scene, camera) //执行渲染操作
      // 浏览器控制台查看相机位置变化
      console.log('camera.position', camera.position)
    }) //监听鼠标、键盘事件
    // onresize 事件会在窗口被调整大小时发生
    window.onresize = function () {
      // 重置渲染器输出画布canvas尺寸
      renderer.setSize(window.innerWidth, window.innerHeight)
      // 全屏情况下：设置观察范围长宽比aspect为窗口宽高比
      camera.aspect = window.innerWidth / window.innerHeight
      // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
      // 但是不会每渲染一帧，就通过相机的属性计算投影矩阵(节约计算资源)
      // 如果相机的一些属性发生了变化，需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
      camera.updateProjectionMatrix()
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
